# -*- coding: utf-8 -*-
# !/usr/bin/python

"""
Crowd fragments api
Crowd相关共通函数

李旭代码 功能参考用
"""

import crowd

from common import dictcm
from common import logcm
from common import loadcfgcm


class CrowdClient:
    cs = None
    isConnecting = False
    groupMap = {}
    tokenMap = {}
    passwordMap = {}

    @staticmethod
    def connect():
        if not CrowdClient.isConnecting:
            cfg = loadcfgcm.load("crowd.json", {})

            app_url = dictcm.get(cfg, "host")
            app_user = dictcm.get(cfg, "user")
            app_pass = dictcm.get(cfg, "password")
            if app_url is None or app_user is None or app_pass is None:
                logcm.print_info("Crowd Server config is empty!")
                return

            try:
                # 连接到Crowd服务器
                logcm.print_info("Connecting Crowd Server: http://%s/ with %s / %s" % (app_url, app_user, app_pass))
                CrowdClient.cs = crowd.CrowdServer("http://%s/" % app_url, app_user, app_pass)

                # 连接成功
                CrowdClient.isConnecting = True

            except Exception as e:
                logcm.print_info("Fail connecting to Crowd Server  : %s" % e, level='error')

    @staticmethod
    def get_login_info(token):
        # 取得登录信息
        username = dictcm.get(CrowdClient.tokenMap, token, "")
        password = dictcm.get(CrowdClient.passwordMap, token, "")
        return (username, password)

    @staticmethod
    def login(username, password):

        # 连接初始化
        CrowdClient.connect()

        if not CrowdClient.isConnecting:
            logcm.print_info("Crowd Server not connecting")
            return None

        if not CrowdClient.cs.auth_user(username, password):
            logcm.print_info("Auth Failed for %s!" % username)
            return None

        # Create a session. The important bit is the token.
        session = CrowdClient.cs.get_session(username, password)
        # logcm.print_obj(session, "session", show_json=True)
        token = session["token"]
        CrowdClient.tokenMap[token] = username
        CrowdClient.passwordMap[token] = password

        # 设置扩展信息
        CrowdClient.setExtInfo(username, session)

        # 登录时，更新group信息
        groups = CrowdClient.cs.get_groups(username)
        # logcm.print_obj(groups, "groups")
        CrowdClient.groupMap[username] = groups

        return session

    @staticmethod
    def setExtInfo(username, session):
        # 扩展登录信息
        jsonFileName = "%s.json" % username
        emptyInfo = {
            "jenkinsToken": "",
            "redmineKey": "",
            "mobile": ""
        }
        extLoginInfo = loadcfgcm.load(jsonFileName, emptyInfo, "./cache/login")
        if session is not None:
            session["ext"] = extLoginInfo

    @staticmethod
    def saveExtInfo(username, key, val):
        """
        保存登录信息
        :param username: 用户名
        :param key: KEY
        :param val: 值
        :return: 无
        """

        jsonFileName = "%s.json" % username
        extLoginInfo = loadcfgcm.load(jsonFileName, {}, "./cache/login")

        extLoginInfo[key] = val

        loadcfgcm.save_cfg_file(extLoginInfo, jsonFileName, "./cache/login")

    @staticmethod
    def getExtInfo(username, key):
        """
        保存登录信息
        :param username: 用户名
        :param key: KEY
        :return: 无
        """

        jsonFileName = "%s.json" % username
        extLoginInfo = loadcfgcm.load(jsonFileName, {}, "./cache/login")

        return dictcm.get(extLoginInfo, key)

    @staticmethod
    def getGroups(username):
        """
        取得组名列表
        :param username: 用户名
        :return: 组名列表
        """

        if username is None:
            return []

        # 连接初始化
        CrowdClient.connect()

        if username in CrowdClient.groupMap:
            return CrowdClient.groupMap[username]

        groups = CrowdClient.cs.get_groups(username)
        logcm.print_obj(groups, "groups")
        CrowdClient.groupMap[username] = groups

        return groups

    @staticmethod
    def isAdmin(username=None, token=None):
        """
        是否管理员
        :param username: 用户名
        :return: 是否
        """
        if username is None and token is None:
            return False

        # 连接初始化
        CrowdClient.connect()

        if token is not None:
            username = dictcm.get(CrowdClient.tokenMap, token)

        if username is None:
            return False

        groups = CrowdClient.getGroups(username)
        if groups is None:
            return False

        logcm.print_obj(groups, "groups for %s" % username)
        if "support-admin" in groups:
            return True

        return False

    @staticmethod
    def hasProdRight(username=None, token=None):
        """
        是否有生产权限
        :param username: 用户名
        :return: 是否
        """

        if username is None and token is None:
            return False

        # 连接初始化
        CrowdClient.connect()

        if token is not None:
            username = dictcm.get(CrowdClient.tokenMap, token)

        if username is None:
            return False

        groups = CrowdClient.getGroups(username)
        if groups is None:
            return False

        logcm.print_obj(groups, "groups for %s" % username)
        if "support-prod" in groups:
            return True

        return False

    @staticmethod
    def hasProdDbRight(username=None, token=None):
        """
        是否有生产权限
        :param username: 用户名
        :return: 是否
        """

        if username is None and token is None:
            return False

        # 连接初始化
        CrowdClient.connect()

        if token is not None:
            username = dictcm.get(CrowdClient.tokenMap, token)

        if username is None:
            return False

        groups = CrowdClient.getGroups(username)
        if groups is None:
            return False

        logcm.print_obj(groups, "groups for %s" % username)
        if "support-prod-db" in groups:
            return True

        return False

    @staticmethod
    def logout(token):
        """
        退出登录
        :param token:
        :return:
        """

        if token is None:
            return

        # 连接初始化
        CrowdClient.connect()

        # 终止会话
        CrowdClient.cs.terminate_session(token)

        # 清空token
        if token in CrowdClient.tokenMap:
            del CrowdClient.tokenMap[token]
        if token in CrowdClient.passwordMap:
            del CrowdClient.passwordMap[token]

        # 清空用户名
        username = dictcm.get(CrowdClient.tokenMap, token)
        if username is not None and username in CrowdClient.groupMap:
            del CrowdClient.groupMap[username]

    @staticmethod
    def validate(token):
        """
        验证Token
        :param token: Token
        :return:
        """

        if token is None or token == "":
            return None

        # 连接初始化
        CrowdClient.connect()

        # Check that the token is valid (and of course it should be).
        session = CrowdClient.cs.validate_session(token)
        # logcm.print_obj(session, "session", show_json=True)

        if not session:
            return None

        # 本地没有必须重新登录
        if token not in CrowdClient.tokenMap:
            username = session["user"]["name"]
            CrowdClient.tokenMap[token] = username
        else:
            username = dictcm.get(CrowdClient.tokenMap, token)

        # 设置扩展信息
        CrowdClient.setExtInfo(username, session)

        return session

    @staticmethod
    def emptyLogin(callback=""):

        loginInfo = {
            "username": "",
            "password": "",
            "callback": callback
        }
        return loginInfo
